package cn.com.websocket.service.impl;

import cn.com.websocket.enums.MessageEnum;
import cn.com.websocket.enums.YesOrNoEnum;
import cn.com.websocket.handle.SocketHandle;
import cn.com.websocket.mapper.MessageFileMapper;
import cn.com.websocket.mapper.MessageMapper;
import cn.com.websocket.po.Message;
import cn.com.websocket.po.MessageFile;
import cn.com.websocket.util.EnumUtil;
import cn.com.websocket.util.GenSequenceUtil;
import cn.com.websocket.util.RegularExpressionUtil;
import cn.com.websocket.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.websocket.Session;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>在线或离线消息</p>
 * */
@Service("onlineOfflineMsgService")
public class OnlineOfflineMsgServiceImpl extends AbsMessageStrategy {

    @Autowired
    MessageMapper messageMapper;
    @Autowired
    MessageFileMapper messageFileMapper;

    @Override
    public void handleMessage(Session session, Message message) {

        MessageEnum.MSG_TYPE msgType = EnumUtil.getEnumByKey(MessageEnum.MSG_TYPE.class,message.getMsgType());
        boolean attachmentMsg = Boolean.FALSE;
        String _oldText = message.getText();
        if(!MessageEnum.MSG_TYPE.TEXT.getKey().equals(msgType.getKey())){
            String base64Message = RegularExpressionUtil.findBase64FilePrefix(_oldText);
            if(StringUtil.isEmpty(base64Message)){
                System.err.println(" base64 格式错误!");
                return;
            }
            attachmentMsg = Boolean.TRUE;
            message.setText(String.format("【%s】",msgType.getValue()));
        }
        // 虽然是在线，但有可能没有读取消息，需要 客户端主动 发送 ack 标志
        message.setId(GenSequenceUtil.nextId());
        message.setCreateTime(new Date());
        message.setRead(YesOrNoEnum.NO.getKey());
        int saveCount = messageMapper.saveMessage(message);
        if(attachmentMsg){
            //         mysql的配置文件my.ini，发现max_allowed_packet值为4M太小了 初始化大小为 4M
            //         计算 base64大小（将数据长度乘以 3/4，因为编码会将 6 个字节变成 8 个字节。如果结果在 4MB 的几个字节之内，那么您需要在最后计算 = 的数量）
            MessageFile messageFile = new MessageFile(message.getId(), _oldText, message.getFileName(), RegularExpressionUtil.findBase64FilePrefix(_oldText));
            int base64Length = messageFile.getData().substring(messageFile.getBase64Prefix().length()).length();
            double fileSize = base64Length * (3d/4);
            String fileType = messageFile.getFileName().substring(messageFile.getFileName().lastIndexOf("."));
            messageFile.setFileType(fileType);
            messageFile.setFileSize(Math.round(fileSize));
            messageFileMapper.saveMessageFile(messageFile);

            message.setData(_oldText);
        }
        //未读消息递增
        String key = SocketHandle.getOfflineMsgKey(message.getSource(),message.getTarget());
        List<Message> messages = SocketHandle.offlineMessage.get(key);
        if(null!=messages){
            messages.add(message);
            SocketHandle.offlineMessage.put(key,messages);
        }else{
            SocketHandle.offlineMessage.put(key, new ArrayList<>(Arrays.asList(message)));
        }
        // 把当前消息追加至缓存，做为历史记录
        putHistoryMessage(message);
        Session targetSession = SocketHandle.sessionPools.get(message.getTarget());
        if(null!=targetSession){
            // 如果对方在线，则立推送消息;
            sendMessage(targetSession,message);
        }
    }

}
